# 08장 인그레스
Assembled by GimunLee
# 인그레스 개념
- 인그레스는 클러스터 외부에서 안으로 접근하는 요청들을 어떻게 처리할지 정의해둔 규칙 모음
- 클러스터 외부에서 접근해야 할 URL을 사용할 수 있도록 하고, 트래픽 로드밸런싱, SSL 인증서 처리, 도메인 기반 가상 호스팅 제공
- 인그레스 자체는 이런 규칙들을 정의해둔 자원이고, 실제로 동작시키는 것은 인그레스 컨트롤러
- ingress-nginx는 인그레스 컨트롤러와 인그레스를 연동하는 도구
- ingress-nginx 컨트롤러는 인그레스에서 설정한 내용을 nginx 환경 설정으로 변경해서 nginx에 적용
# 인그레스 설정
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: test
annotations: # 인그레스 설정할 때 하위 필드 사용
nginx.ingress.kubernetes.io/rewrite-target: / # / 경로로 리다이렉트
spec: # 하위 필드에 어떤 규칙을 사용할지 지정
rules:
- host: foo.bar.com # 이 주소로 요청이 들어오면
http:
paths:
- path: /foos1 # 해당 path로 접근하면
backend: # 해당 서비스로 전송
serviceName: s1
servicePort: 80
- path: /bars2
backend:
serviceName: s2
servicePort: 80
- host: bar.foo.com
http:
paths:
- backend:
serviceName: s2
servicePort: 80
# ingress-nginx 컨트롤러
- 인그레스는 설정일 뿐이고 설정 내용대로 동작하는 실제 주체는 인그레스 컨트롤러
- 쿠버네티스가 공식적으로 제공하는 것은 구글 컴퓨트 엔진용 ingress-gce와 nginx용 ingress-nginx
# 인그레스 SSL 설정하기
- 인그레스를 이용하면 요청으로 들어오는 트래픽에 다양한 설정을 할 수 있음
- 인그레스로 SSL 인증서를 설정하면 파드 각각에 SSL 설정을 따로 할 필요가 없어 편리함
- SSL 인증서 기한이 만료됐을 때도 인그레스에서만 인증서를 업데이트하면 됨
# SSL 인증서 설정
$ kubectl create secret tls kube-book-secret --key tls.key --cert tls.crt
# 시크릿을 인그레스에 적용하는 설정
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-ssl
spec:
tls:
- hosts:
- kube-book.com # 호스트 네임
secretName: kube-book-secret # 만든 시크릿 이름
rules:
- host: kube-book.com
http:
paths:
- path: /
backend:
serviceName: s1
servicePort: 80
# 무중단 배포를 할 때 주의할 점
- 새로운 파드(v2)가 생성되고 헬스 체크가 성공한 후 트래픽을 파드(v2) 쪽으로 전송
- 그후 파드(v1) 쪽으로 보내던 트래픽을 중단한 후 파드(v1)을 제거
# maxSurge와 maxUnavailable 필드 설정
- 파드 관리를 RollingUpdate로 설정했을 때 .maxSurge와 .maxUnavailable 필드 설정이 필요
- 디플로이먼트를 이용해서 컨테이너를 배포할 때 .maxSurge 필드에는 디플로이먼트에 설정된 기본 파드 개수에 여분의 파드를 몇개 추가할 수 있는지 설정 가능
- .maxUnavailalbe 필드에는 디플로이먼트를 업데이트하는 동안 몇 개의 파드를 이용할 수 없어도 되는지 설정
# 파드가 readinessProbe를 지원하는지 확인
- 무중단 배포에서 신경 써서 봐야할 프로브는 readinessProbe
- readinessProbe는 실제로 컨테이너가 서비스 요청을 처리할 준비가 되었는지 진단
- readinessProbe가 OK 상태여야 해당 파드와 연결된 서비스에 파드의 IP가 추가되고 트래픽을 받을 수 있음
- 컨테이너 자체에 readinessProbe를 설정하기 어려운 상황이라면 .spec.minReadySeconds 필드를 이용해 어느 정도 readinessProbe와 비슷한 효과를 낼 수 있음
# 쿠버네티스와 컨테이너 안에 그레이스풀 종료 설정
- 노드 안 컨테이너를 관리하는 컴포넌트인 kubelet은 새 파드가 실행되고 이전 파드를 종료할 때 파드에 SIGTERM 신호를 먼저 전송
- 무중단 배포를 하려면 컨테이너에서 SIGTERM 신호를 받았을 때 기존에 받은 요청만 처리를 완료하고 새 요청을 받지 않는 그레이스풀 종료가 설정되어 있어야함
- kubelet에서 파드에 SGTERM 신호를 보낸 후 일정 시간동안 그레이스풀 종료가 되지 않으면 강제로 SIGKILL 신호를 보내서 파드를 종료
- 대기 시간은 .terminationGracePeriodSeconds 필드로 설정 가능(기본 대기 시간은 30초)
- 그레이스풀 종료를 설정하지 못할 때, 프리스톱 훅(prestop hook)을 이용할 수 있음
- 쿠버네티스에서는 파드 생명 주기 중 훅을 설정할 수 있는데, 파드가 실행된 직후 실행하는 포스트스타트 훅과 파드가 종료되기 직전 실행되는 프리스톱 훅
- 하지만 이렇게 프리스톱 훅으로 대기 시간을 설정하더라도 .terminationGracePeriodSeconds 필드에 설정한 대기 시간을 초과한다면 프로세스 종료 발생 가능
# 무중단 배포 테스트
# deployment.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: websample
spec:
selector:
matchLabels:
run: websample
strategy:
rollingUpdate:
maxSurge: 25% # 기본 파드 개수의 25%만큼 파드를 더 추가할 수 있음
maxUnavailable: 25% # 디플로이먼트를 업데이트하는 동안 기본 파드 개수의 25%만큼의 파드를 이용할 수 없음
type: RollingUpdate
template:
metadata:
labels:
run: websample
spec:
containers:
- image: acadx0/190713:v1
imagePullPolicy: Always
name: websample
ports:
- containerPort: 5000
protocol: TCP
livenessProbe:
httpGet: # HTTPGetAction 핸들러를 사용해 컨테이너 진단
path: /liveness
port: 5000
readinessProbe:
httpGet: # HTTPGetAction 핸들러를 사용해 컨테이너 진단
path: /readiness
port: 5000
lifecycle:
preStop:
httpGet:
path: /prestop
port: 5000
terminationGracePeriodSeconds: 30
# ingress.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: websample-ing
spec:
rules:
- host: http://127.0.0.1.xip.io
http:
paths:
- backend:
serviceName: websample
servicePort: 5000
path: /
- 지속적 요청을 보내며 배포 테스트를 진행할 수 있는 베게타라는 부하 테스트 도구 이용해 진행
- 실시간 모니터링 도구 스턴(stern)의
stern websample
명령으로 로그를 확인해보면 애플리케이션 측명에서의 무중단 배포 과정을 좀 더 쉽게 확인 가능
# Referenses
- 쿠버네티스 입문 - 90가지 예제로 배우는 컨테이너 관리 자동화 표준 / 동양북스
← 07장 서비스 레이블과 애너테이션 →